<?php
/**
* Websocket server
* It's also be http server
*/
class Ws
{	
	CONST HOST = "0.0.0.0";
	CONST PORT = 8811;
	CONST CHART_PORT = 8812;

	public $ws = null;
	
	public function __construct()
	{   
//            require_once __DIR__.'/../thinkphp/start.php';
//            \app\common\lib\Redis::getInstance()->del(config('redis.live_push'));
		//use swoole ws
		$this->ws = new swoole_websocket_server(self::HOST,self::PORT);

		//listen chart port
		$this->ws->listen(self::HOST,self::CHART_PORT,SWOOLE_SOCK_TCP);

		$this->ws->set(
			[
				'enable_static_handler' => true,
				'document_root' => "/home/tang/localspace/live/tp5/public/static",
				'worker_num' => 2,
				'task_worker_num' => 2
			]
		);

		//callback
		$this->ws->on("start",[$this, 'onStart']);
		$this->ws->on("open",[$this, 'onOpen']);
		$this->ws->on("message",[$this, 'onMessage']);
		$this->ws->on("workerstart",[$this, 'OnWorkerStart']);
		$this->ws->on("request",[$this, 'onRequest']);
		$this->ws->on("task",[$this, 'onTask']);
		$this->ws->on("finish",[$this, 'onFinish']);
		$this->ws->on("close",[$this, 'onClose']);

		$this->ws->start();
	}

	/**
	 * server start
	 * @return [type] [description]
	 */
	public function onStart($server)
	{	
            swoole_set_process_name("live_master");
	}

	/**
	 * worker start
	 * @param obj $server    
	 * @param int $worker_id
	 */
	public function OnWorkerStart($server,$worker_id)
	{
		define('APP_PATH', __DIR__.'/../application/');

		require_once __DIR__.'/../thinkphp/start.php';
	}

	/**
	 * http request
	 * @param  [type] $request [description]
	 * @param  [type] $respone [description]
	 * @return [type]          [description]
	 */
	public function onRequest($request,$respone)
	{	
		if ($request->server['request_uri'] == '/favicon.ico') {
			$respone->status(404);
			$respone->end();
			return;
		}

		$_SERVER = [];
		if(isset($request->server)){
			foreach ($request->server as $key => $value) {
				$_SERVER[strtoupper($key)] = $value;
			}
		}
		if(isset($request->header)){
			foreach ($request->header as $key => $value) {
				$_SERVER[strtoupper($key)] = $value;
			}
		}

		$_GET = [];
		if(isset($request->get)){
			foreach ($request->get as $key => $value) {
				$_GET[$key] = $value;
			}
		}

		$_POST = [];
		if(isset($request->post)){
			foreach ($request->post as $key => $value) {
				$_POST[$key] = $value;
			}
		}

		$_FILES = [];
		if(isset($request->files)){
			foreach ($request->files as $key => $value) {
				$_FILES[$key] = $value;
			}
		}

		$_POST['http_server'] = $this->ws;

		ob_start();

		try {
			$res2 = think\Container::get('app',[APP_PATH])
			->run()
			->send();
		} catch (\Exception $e) {
			
		}

		$res = ob_get_contents();
		if($res){
			ob_end_clean();
		}

		$respone->end($res);
	}

	// async task
	public function onTask($server,$taskId,$workerId,$data)
	{	
		//distribution task
		$obj = new app\common\lib\Task;
                $method = $data['method'];
		$flag = $obj->$method($data['data'],$server);

		return $flag;
	}

	//async task finish
	public function onFinish($server,$taskId,$data)	
	{
		echo "taskId:{$taskId}".PHP_EOL;

		echo "finish-data-success:{$data}".PHP_EOL;
	}

	//ws server link
	public function onOpen($ws,$request)
	{
            \app\common\lib\Redis::getInstance()->sAdd(config('redis.live_push'),$request->fd);
	}

	//ws client send msg and server get msg
	public function onMessage($ws,$frame)
	{
//		echo "data is : {$frame->data}".PHP_EOL;
	}

	//ws client close
	public function onClose($ws,$fd)
	{   
            \app\common\lib\Redis::getInstance()->sRem(config('redis.live_push'),$fd);
	}
}

new Ws();